/*
 *Copyright (c) [2019-2020]  C2comm, Inc.  All rights reserved.
 *
 *This program is free software; you can redistribute it and/or
 *modify it under the terms of the GNU General Public License
 *as published by the Free Software Foundation; either version 2
 *of the License, or (at your option) any later version.
 *
 *This program is distributed in the hope that it will be useful,
 *but WITHOUT ANY WARRANTY; without even the implied warranty of
 *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *GNU General Public License for more details.
 *
 *You should have received a copy of the GNU General Public License
 *along with this program; If not, see <https://www.gnu.org/licenses/>
 */
/*
 *Vendor: C2comm
 *Version: 1.0
 *Filename: SMSyncCompute.v
 *Target Device: Altera
 *Author : sunxiaotian@c2comm.cn
*/

`timescale 1ns/1ps
module SMSyncCompute(
    input  wire         SYS2CORE_clk,
    input  wire         SYS2CORE_rst_n,
                       
    input  wire [348:0] CONF2CORE_sm_static_conf,
    input  wire [ 27:0] CONF2CORE_dbg_conf,
    input  wire [19 :0] G_local_clk,
    input  wire [5  :0] G_integration_cycle,
    
    input  wire         G_pcf_des_valid,
    input  wire [90 :0] G_pcf_des, 
    
    //output reg          SC2LCC_clock_corr_valid,
    output reg  [19 :0] SC2LCC_clock_corr,
    
    output wire          SC2CD_sync_des_valid,
    output wire  [8:0]   SC2CD_sync_des,
    
    output wire [332:0] CORE2MON_sm_state
);
//***************************************************
//            Intermediate variable Declaration
//***************************************************
//all wire/reg/parameter variable 
//should be declare below here 
wire [19:0] start_acceptance_window;
wire [19:0] end_acceptance_window;
wire best_pcf_des_judge;
wire IN_TYPE;//标识接收的G_pcf_des描述符帧类型为IN帧
wire in_scheduled;//标识接收的G_pcf_des描述符，是否在接受窗口内
wire [3:0]  curr_bin_memb_num;//记录当前G_pcf_des描述符中membership字段的位累加值
reg  [3:0]  best_bin_memb_num;//记录在接受窗口内的membership字段的位累加值中的最大值

wire [19:0] user_dbg_corr;//用户调试时定义的时钟偏移 
//***************************************************
//       状态统计信息处理
//***************************************************
assign CORE2MON_sm_state[332:286] = 47'b0;
assign CORE2MON_sm_state[285:266] = SC2LCC_clock_corr;
assign CORE2MON_sm_state[265:0] = 266'b0;

//***************************************************
//            接受窗口判断
//***************************************************
//smc_scheduled_receive_pit-acceptance_window/2
assign start_acceptance_window = CONF2CORE_sm_static_conf[79:60] - CONF2CORE_sm_static_conf[303:285];

//smc_scheduled_receive_pit+acceptance_window/2
assign end_acceptance_window = CONF2CORE_sm_static_conf[79:60] + CONF2CORE_sm_static_conf[303:285];

assign curr_bin_memb_num = G_pcf_des[15] + G_pcf_des[14] + 
                            G_pcf_des[13] + G_pcf_des[12] + 
                            G_pcf_des[11] + G_pcf_des[10] + 
                            G_pcf_des[9]  + G_pcf_des[8];
							
assign IN_TYPE = (G_pcf_des_valid == 1'b1) && (G_pcf_des[17:16]== 2'b10);
						
assign in_scheduled = (G_pcf_des[37:18]>=start_acceptance_window) && (G_pcf_des[37:18]<=end_acceptance_window) && (G_integration_cycle == G_pcf_des[7:2]);		

assign best_pcf_des_judge = (IN_TYPE == 1'b1) && (in_scheduled == 1'b1) && (best_bin_memb_num < curr_bin_memb_num);		
						
assign SC2CD_sync_des_valid = (IN_TYPE == 1'b1) && (in_scheduled == 1'b0 || best_pcf_des_judge == 1'b1);
assign SC2CD_sync_des = {~in_scheduled,G_pcf_des[15:8]};





//***************************************************
//            选择接受窗口内最优帧
//***************************************************	

assign user_dbg_corr = (G_integration_cycle == CONF2CORE_dbg_conf[25:20]) ? CONF2CORE_dbg_conf[19:0] : 20'b0;
						
always @(posedge SYS2CORE_clk or negedge SYS2CORE_rst_n) begin
    if(!SYS2CORE_rst_n) begin
		SC2LCC_clock_corr[19:0] <= 20'b0;
		best_bin_memb_num <= 4'b0;
    end
    else begin
	
	
		if((G_local_clk < start_acceptance_window)||(G_local_clk>=CONF2CORE_sm_static_conf[19:0])) begin
			SC2LCC_clock_corr[19:0] <= 20'b0;
			best_bin_memb_num <= 4'b0;
		end
		else if((G_local_clk <= end_acceptance_window)&&best_pcf_des_judge==1'b1)begin
			best_bin_memb_num <= curr_bin_memb_num;
            SC2LCC_clock_corr <= CONF2CORE_sm_static_conf[79:60]-G_pcf_des[37:18] + user_dbg_corr;//add by lxj 20200526
        end
        else begin 
			best_bin_memb_num <= best_bin_memb_num;
			SC2LCC_clock_corr[19:0] <= SC2LCC_clock_corr[19:0];
        end
    end
end

endmodule